package cn.zyjblogs.netty.simple;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 说明
 * 1、自定义一个Handler 需要继承netty规定好的某个HandlerAdapter
 */
public class NIOServerHandler extends ChannelInboundHandlerAdapter {

    private ReentrantLock lock =new ReentrantLock();

    /**
     * 读取数据实际（这里我们可以读取客户端发送的消息）
     *
     * @param ctx 上下文对象 含有管道pipeline 通道channel和地址
     * @param msg 客户端发送的数据 默认Object
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        /**
         * 比如这里我们有一个非常耗时的业务 -> 异步执行 ->提交该channel 对应的NIOEventLoop 的taskQueue中
         */
        ctx.channel().eventLoop().execute(() -> {
            try {
                Thread.sleep(5 * 1000);
                ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端~o( =∩ω∩= )m喵 || 2", CharsetUtil.UTF_8));
            } catch (InterruptedException e) {
                System.out.println("发生异常");
            }
        });
        ctx.channel().eventLoop().execute(() -> {
            try {
                Thread.sleep(5 * 1000);
                ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端~o( =∩ω∩= )m喵 || 3", CharsetUtil.UTF_8));
            } catch (InterruptedException e) {
                System.out.println("发生异常");
            }
        });
        //用户自定义定时任务 -> 该任务是提交到scheduleTaskQueue中
        ctx.channel().eventLoop().scheduleAtFixedRate(() -> {
            try {
                Thread.sleep(5 * 1000);
                ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端~o( =∩ω∩= )m喵 || 4 定时任务", CharsetUtil.UTF_8));
            } catch (InterruptedException e) {
                System.out.println("发生异常");
            }
        },1,3L, TimeUnit.SECONDS);
        System.out.println("go on .....");

       /* System.out.println("服务器读取线程"+Thread.currentThread().getName());
        //        super.channelRead(ctx, msg);
        System.out.println("server ctx = " + ctx);
        System.out.println("看看channel 和 pipeline的关系");
        //Channel channel = ctx.channel();
        //本质是一个双线链表
        // ChannelPipeline pipeline = ctx.pipeline();
        ByteBuf buf = (ByteBuf) msg;
        System.out.println("客户端发送消息是："+buf.toString(CharsetUtil.UTF_8));
        System.out.println("客户端地址： "+ ctx.channel().remoteAddress());*/
    }

    //数据读取完毕
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // super.channelReadComplete(ctx);
        //writeAndFlush  是write和flush 方法  将数据写入到缓存 并刷新
        //一般将，我们需要对发送数据进行编码
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端~o( =∩ω∩= )m喵 || 1", CharsetUtil.UTF_8));
    }

    //处理异常 一般是需要关闭通道
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // super.exceptionCaught(ctx, cause);
        ctx.close();
    }
}
